//-----------------------------------------------------------------------
// <copyright file="Delete.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Sdc.Tasks.BizTalk2006.Application
{
    using System.Collections.Generic;
    using System.Globalization;
    using Microsoft.BizTalk.ExplorerOM;
    using Microsoft.Build.Framework;
    using Microsoft.Sdc.Tasks.BizTalk2004;

    /// <summary>
    /// Deletes an Application, and all its child objects
    /// </summary>
    public class Delete : BizTalk2004TaskBase
    {
        private readonly Queue<string> orderedDelete;
        private string application;

        /// <summary>
        /// Constructor of the Delete
        /// </summary>
        public Delete()
        {
            this.orderedDelete = new Queue<string>();
        }

        /// <summary>
        /// Gets or sets the application.
        /// </summary>
        /// <value>The application.</value>
        [Required]
        public string Application
        {
            get { return this.application; }
            set { this.application = value; }
        }

        /// <summary>
        /// This is the main execute method that all tasks should implement
        /// </summary>
        /// <remarks>
        /// TaskException should be thrown in the event of errors
        /// </remarks>
        protected override void InternalExecute()
        {
            this.OrderedApplicationDelete(this.Application);

            using (BtsCatalogExplorer explorer = this.GetBtsCatalogExplorer(this.Server, this.Database))
            {
                using (Microsoft.BizTalk.ApplicationDeployment.Group group = new Microsoft.BizTalk.ApplicationDeployment.Group())
                {
                    group.DBName = this.Database;
                    group.DBServer = this.Server;

                    Microsoft.BizTalk.ApplicationDeployment.ApplicationCollection apps = group.Applications;
                    apps.UiLevel = 2;

                    foreach (string applicationName in this.orderedDelete)
                    {
                        Microsoft.BizTalk.ApplicationDeployment.Application app = apps[applicationName];
                        Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "Removing Application {0}", applicationName));
                        apps.Remove(app);
                    }
                }
            }
        }

        /// <summary>
        /// Create a list with applications in the correct order, to delete dependant applications.
        /// </summary>
        /// <param name="applicationName">Name of the application.</param>
        private void OrderedApplicationDelete(string applicationName)
        {
            using (BtsCatalogExplorer explorer = this.GetBtsCatalogExplorer(this.Server, this.Database))
            {
                ApplicationCollection apps = explorer.Applications;

                Application app = apps[applicationName];

                // Add dependend applications before deleting the current application.
                foreach (Application referencedApp in app.BackReferences)
                {
                    string appName = referencedApp.Name;

                    // Check 
                    if (!this.orderedDelete.Contains(appName))
                    {
                        this.OrderedApplicationDelete(appName);
                    }
                }

                // Finally delete current application.
                if (!this.orderedDelete.Contains(applicationName))
                {
                    this.orderedDelete.Enqueue(applicationName);
                    Log.LogMessage(string.Format(CultureInfo.InvariantCulture, "OrderedApplicationDelete list Queued application: {0}", applicationName));
                }
            }
        }
    }
}
